import{ generateAESKey,  decryptAES} from './aes'
// 使用 RSA-OAEP 公钥加密数据
async function encryptWithOAEP(data, publicKeyPem) {
  // 将 PEM 格式的公钥转换为 CryptoKey
  const publicKey = await importPublicKey(publicKeyPem);

  // 加密数据
  const encoder = new TextEncoder();
  const encryptedBuffer = await window.crypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
    },
    publicKey,
    encoder.encode(data)
  );

  // 返回 Base64 编码的加密数据
  return arrayBufferToBase64(encryptedBuffer);
}

// 将 PEM 格式的公钥导入为 CryptoKey
async function importPublicKey(publicKeyPem) {
  const pemHeader = "-----BEGIN PUBLIC KEY-----";
  const pemFooter = "-----END PUBLIC KEY-----";
  const pemContents = publicKeyPem
    .replace(pemHeader, "")
    .replace(pemFooter, "")
    .replace(/\s+/g, ""); // 移除空白字符 

  const binaryDerString = window.atob(pemContents);
  const binaryDer = new Uint8Array(binaryDerString.length);
  for (let i = 0; i < binaryDerString.length; i++) {
    binaryDer[i] = binaryDerString.charCodeAt(i);
  }

  // 导入公钥
  const publicKey = await window.crypto.subtle.importKey(
    "spki",
    binaryDer.buffer,
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    true,
    ["encrypt"]
  );

  return publicKey;
}

// 将 ArrayBuffer 转换为 Base64 字符串
function arrayBufferToBase64(buffer) {
  let binary = "";
  const bytes = new Uint8Array(buffer);
  const len = bytes.byteLength;
  for (let i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return window.btoa(binary);
}
//上面为实现encrypt的代码

function isWeapp() {
  return typeof wx !== 'undefined' 
    && typeof wx.getSystemInfoSync === 'function'
    && !!window.__wxConfig; // 小程序特有
}

async function getPublicKeyFromServer() {
	try {
		let response;
		if(isWeapp()){
			response = await wx.request('http://localhost:3000/api/public-key');
		}
		else{
			response = await fetch('http://localhost:3000/api/public-key');
		}
	
		if (!response.ok) throw new Error('获取公钥失败');
		// console.log('公钥获取成功\n', response);
		return (await response.json()).publicKey;
	} catch (error) {
		console.error('公钥获取失败:', error);
		throw error;
	}
}


async function encryptData(data) {
  try {
    const publicKey = await getPublicKeyFromServer();
    if (!publicKey) throw new Error('无效的公钥');
	// console.log(isWeapp());
    if(isWeapp()){
		return new Promise((resolve, reject) => {	
			wx.rsa.encrypt({
				key: publicKey,
				data: JSON.stringify(data),
				padding: 'RSAES-OAEP',
				hash: 'SHA-256',
				success: res => resolve(res.result),   // Base64
				fail: reject
			});
		});
	}
	return encryptWithOAEP(JSON.stringify(data), publicKey);
  } catch (error) {
    console.error('加密失败:', error);
    throw error;
  }
}
// 安全请求封装
export async function secureFetch(endpoint, params) {
	const aesKey = generateAESKey();
	// console.log('AES key:', aesKey);
	const encryptedAESKey = await encryptData(aesKey);//RSA加密 AES 密钥
	const encryptedParams = await encryptData(params);//RSA加密请求内容
	let response;
	if(isWeapp()){
		const baseURL = 'http://localhost:3000/api';
		response = await wx.request({
			url: baseURL + endpoint,
			method: 'POST',
			data: { encryptedAESKey, encryptedParams },
			header: { 'content-type': 'application/json' }
		});
	}
	else{
		response = await fetch(`http://localhost:3000/api${endpoint}`, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json'
			},
			body: JSON.stringify({ 
				encryptedAESKey: encryptedAESKey,
				encryptedData: encryptedParams 
			})
		});
	}
	console.log('数据获取成功\n', response);
	const results = await response.json();
	const decryptedData = decryptAES(results.encryptedData, aesKey, results.iv);
	// console.log('数据解密成功\n', decryptedData);
	return decryptedData;
}